//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of your Microsoft Windows CE
// Source Alliance Program license form.  If you did not accept the terms of
// such a license, you are not authorized to use this source code.
//
//
//
#include <windows.h>
#include <tchar.h>
#include <tux.h>
#include <kato.h>
#include <shellproc.h>
#include <ceddk.h>
#include <nled.h>
#include "nled_pdd.h"
#include "nled_test.h"
#include "log.h"


#define     TOTAL_SYSTEM_LEDS       1

//------------------------------------------------------------------------------

extern LPCWSTR g_szTestGroupName = L"nled";

//------------------------------------------------------------------------------

extern FUNCTION_TABLE_ENTRY g_lpFTE[] = {
    { L"Notification LEDs On/Off", 0, 0, 1, TestNotificationLeds},
    { L"Test All Leds", 0, 0, 3, TestLeds},
    { L"Test Blinking", 0, 0, 4, TestBlink},
    { L"Test Blinking Rates", 0, 0, 5, TestBlinkRates},
    { L"Test API NLedGetDeviceInfo", 0, 0, 10, TestAPINLedGetDeviceInfo},
    { L"Neg: Test Unavailable Leds", 0, 0, 11, NegTestUnavailableLeds},
    { L"Neg: Test Set Invalid State", 0, 0, 12, NegTestInvalidState},

    { NULL, 0, 0, 0, NULL }
};

//------------------------------------------------------------------------------

BOOL ParseCommands(INT argc, LPTSTR argv[])
{
    return TRUE;
}

//------------------------------------------------------------------------------

BOOL PrepareToRun()
{
    return TRUE;      
}

//------------------------------------------------------------------------------

BOOL FinishRun()
{
    return TRUE;
}


//------------------------------------------------------------------------------

BOOL TurnLedOn( UCHAR LedNumber )
{
    NLED_SETTINGS_INFO SettingsInfo;
    BOOL nled_result;

    SettingsInfo.LedNum = LedNumber;
    SettingsInfo.OffOnBlink = 1;
    LogMsg(L"Setting device 0x%x ON.\r\n",SettingsInfo.LedNum);
    nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);

    return nled_result;
}

BOOL TurnLedOff( UCHAR LedNumber )
{
    NLED_SETTINGS_INFO SettingsInfo;
    BOOL nled_result;

    SettingsInfo.LedNum = LedNumber;
    SettingsInfo.OffOnBlink = 0;
    LogMsg(L"Setting device 0x%x ON.\r\n",SettingsInfo.LedNum);
    nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);

    return nled_result;
}

BOOL BlinkLed( UCHAR LedNumber )
{
    NLED_SETTINGS_INFO SettingsInfo;
    BOOL nled_result, result=FALSE;
    
    SettingsInfo.LedNum = LedNumber;
    SettingsInfo.OffOnBlink = 1;
    LogMsg(L"Setting device 0x%x ON.\r\n",SettingsInfo.LedNum);
    nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);

    if( !nled_result )
        goto cleanUp;

    Sleep(500);

    SettingsInfo.OffOnBlink = 0;
    LogMsg(L"Setting device 0x%x OFF.\r\n",SettingsInfo.LedNum);
    nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);

    if( !nled_result )
        goto cleanUp;

    result = TRUE;
    
cleanUp:
    return result;
}


//------------------------------------------------------------------------------

TEST_FUNCTION(TestNotificationLeds)
{
    TEST_ENTRY;

    INT result = TPR_FAIL;
    UINT lednumber;
    BOOL nled_result;
    NLED_COUNT_INFO countInfo;
    
    LogMsg(L"Test GSample Notification Leds\r\n");

    nled_result = NLedGetDeviceInfo( NLED_COUNT_INFO_ID, &countInfo);
    if ( !nled_result )
    {
        LogMsg(L"Error: COuld not get NLed device driver info.\r\n");
        goto cleanUp;
    }

    LogMsg(L"LED count reported by driver = 0x%x.\r\n",countInfo.cLeds);

    // We expect a set number of LEDs.  This includes the vibrator
    if( countInfo.cLeds != TOTAL_SYSTEM_LEDS )
    {
        LogMsg(L"GSample reported unexpect (%d) number of system leds.  Expected %d leds.\r\n",countInfo.cLeds, TOTAL_SYSTEM_LEDS);
        goto cleanUp;
    }


    for(lednumber=0;lednumber<1;lednumber++)
    {
        LogMsg(L"Blinking led %d.\r\n",lednumber);
        if( !BlinkLed( lednumber ) )
        {
            LogMsg(L"Blink led failure for led %d.\r\n", lednumber);
            goto cleanUp;
        }

        Sleep(500);
    }

    result = TPR_PASS;

cleanUp:
    return result;
}

//------------------------------------------------------------------------------


TEST_FUNCTION(TestLeds)
{
    TEST_ENTRY;
    INT result = TPR_FAIL;
    BOOL nled_result;
    int lednumber;

    NLED_COUNT_INFO countInfo;
    NLED_SETTINGS_INFO SettingsInfo;

   
    LogMsg(L"Test All Leds\r\n");

    nled_result = NLedGetDeviceInfo( NLED_COUNT_INFO_ID, &countInfo);
    if ( !nled_result )
    {
        LogMsg(L"Error: COuld not get NLed device driver info.\r\n");
        goto cleanUp;
    }

    LogMsg(L"LED count reported by driver = 0x%x.\r\n",countInfo.cLeds);

    // We expect a set number of LEDs.  This includes the vibrator
    if( countInfo.cLeds != TOTAL_SYSTEM_LEDS )
    {
        LogMsg(L"GSample reported unexpect (%d) number of system leds.  Expected %d leds.\r\n",countInfo.cLeds, TOTAL_SYSTEM_LEDS);
        goto cleanUp;
    }

    for(lednumber=0;lednumber<(int)countInfo.cLeds;lednumber++)
    {
        SettingsInfo.LedNum = lednumber;
        SettingsInfo.OffOnBlink = 1;
        LogMsg(L"Setting device 0x%x ON.\r\n",SettingsInfo.LedNum);
        nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);
        Sleep(500);
    }

    for(lednumber=countInfo.cLeds-1;lednumber>=0;lednumber--)
    {
        SettingsInfo.LedNum = lednumber;
        SettingsInfo.OffOnBlink = 0;
        LogMsg(L"Setting device 0x%x OFF.\r\n",SettingsInfo.LedNum);
        nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);
        Sleep(500);
    }

    result = TPR_PASS;
    
cleanUp:
    return result;
}


TEST_FUNCTION(TestBlink)
{
    TEST_ENTRY;
    INT result = TPR_FAIL;
    BOOL nled_result;
    int lednumber;

    NLED_COUNT_INFO countInfo;
    NLED_SETTINGS_INFO SettingsInfo;

   
    LogMsg(L"Test Blinking\r\n");

    nled_result = NLedGetDeviceInfo( NLED_COUNT_INFO_ID, &countInfo);
    if ( !nled_result )
    {
        LogMsg(L"Error: COuld not get NLed device driver info.\r\n");
        goto cleanUp;
    }

    LogMsg(L"LED count reported by driver = 0x%x.\r\n",countInfo.cLeds);

    // We expect a set number of LEDs.  This includes the vibrator
    if( countInfo.cLeds != TOTAL_SYSTEM_LEDS )
    {
        LogMsg(L"GSample reported unexpect (%d) number of system leds.  Expected %d leds.\r\n",countInfo.cLeds, TOTAL_SYSTEM_LEDS);
        goto cleanUp;
    }

    SettingsInfo.OnTime = 126 * 1000;
    SettingsInfo.OffTime = 126 * 1000;
    SettingsInfo.MetaCycleOn = 0;
    SettingsInfo.MetaCycleOff = 0;

    for(lednumber=0;lednumber<(int)countInfo.cLeds;lednumber++)
    {
        SettingsInfo.LedNum = lednumber;
        SettingsInfo.OffOnBlink = NLED_STATE_BLINKING;
        LogMsg(L"Setting device 0x%x Blinking.\r\n",SettingsInfo.LedNum);
        nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);
        Sleep(1500);
        SettingsInfo.OffOnBlink = 0;
        LogMsg(L"Setting device 0x%x OFF.\r\n",SettingsInfo.LedNum);
        nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);
    }

    Sleep(1000);

    for(lednumber=0;lednumber<(int)countInfo.cLeds;lednumber++)
    {
        SettingsInfo.LedNum = lednumber;
        SettingsInfo.OffOnBlink = NLED_STATE_BLINKING;
        LogMsg(L"Setting device 0x%x BLINKING.\r\n",SettingsInfo.LedNum);
        nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);
        Sleep(500);
    }
    Sleep(5000);
    for(lednumber=0;lednumber<(int)countInfo.cLeds;lednumber++)
    {
        SettingsInfo.LedNum = lednumber;
        SettingsInfo.OffOnBlink = 0;
        LogMsg(L"Setting device 0x%x OFF.\r\n",SettingsInfo.LedNum);
        nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);
        Sleep(400);
    }

    Sleep(5000);

    for(lednumber=0;lednumber<(int)countInfo.cLeds;lednumber++)
    {
        SettingsInfo.LedNum = lednumber;
        SettingsInfo.OffOnBlink = NLED_STATE_BLINKING;
        LogMsg(L"Setting device 0x%x BLINKING.\r\n",SettingsInfo.LedNum);
        nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);
        Sleep(2000);
        SettingsInfo.OffOnBlink = 1;
        LogMsg(L"Setting device 0x%x ON.\r\n",SettingsInfo.LedNum);
        nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);
        Sleep(1000);
        SettingsInfo.OffOnBlink = 0;
        LogMsg(L"Setting device 0x%x OFF.\r\n",SettingsInfo.LedNum);
        nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);
    }
        
    result = TPR_PASS;
    
cleanUp:
    return result;
}


//------------------------------------------------------------------------------

TEST_FUNCTION(TestBlinkRates)
{
    TEST_ENTRY;
    INT result = TPR_FAIL;
    BOOL nled_result;
    int lednumber;

    NLED_COUNT_INFO countInfo;
    NLED_SETTINGS_INFO SettingsInfo;

   
    LogMsg(L"Test Blinking Rates\r\n");

    nled_result = NLedGetDeviceInfo( NLED_COUNT_INFO_ID, &countInfo);
    if ( !nled_result )
    {
        LogMsg(L"Error: Could not get NLed device driver info.\r\n");
        goto cleanUp;
    }

    LogMsg(L"LED count reported by driver = 0x%x.\r\n",countInfo.cLeds);

    // We expect a set number of LEDs.  This includes the vibrator
    if( countInfo.cLeds != TOTAL_SYSTEM_LEDS )
    {
        LogMsg(L"GSample reported unexpect (%d) number of system leds.  Expected %d leds.\r\n",countInfo.cLeds, TOTAL_SYSTEM_LEDS);
        goto cleanUp;
    }

    SettingsInfo.OnTime = 0;
    SettingsInfo.OffTime = 0;
    SettingsInfo.MetaCycleOn = 0;
    SettingsInfo.MetaCycleOff = 0;
    
    for(lednumber=0;lednumber<(int)countInfo.cLeds;lednumber++)
    {
        SettingsInfo.LedNum = lednumber;
        SettingsInfo.OffOnBlink = NLED_STATE_BLINKING;

        for( SettingsInfo.OnTime = 0; SettingsInfo.OnTime < 1200*1000; SettingsInfo.OnTime += 75*1000 )
        {
            SettingsInfo.OffTime = SettingsInfo.OnTime;

            LogMsg(L"Setting device 0x%x Equal Rate Blinking (%dms).\r\n",
                SettingsInfo.LedNum,
                SettingsInfo.OnTime / 1000);

            nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);
            Sleep( 2000 );
        }
        
        SettingsInfo.OffOnBlink = 0;
        nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);
    }

    for( SettingsInfo.OnTime = 0; SettingsInfo.OnTime < 1200*1000; SettingsInfo.OnTime += 75*1000 )
    {
        SettingsInfo.OffOnBlink = NLED_STATE_BLINKING;
        SettingsInfo.OffTime = 65*1000;

        for(lednumber=0;lednumber<(int)countInfo.cLeds;lednumber++)
        {
            SettingsInfo.LedNum = lednumber;

            LogMsg(L"Setting device 0x%x Unequal Rate Blinking (on=%dms,off=%dms).\r\n",
                SettingsInfo.LedNum,
                SettingsInfo.OnTime / 1000,
                SettingsInfo.OffTime / 1000);

            nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);
        }

        Sleep( 4000 );
    }

    for(lednumber=0;lednumber<(int)countInfo.cLeds;lednumber++)
    {
        SettingsInfo.LedNum = lednumber;
        SettingsInfo.OffOnBlink = 0;
        nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);
    }

    result = TPR_PASS;
    
cleanUp:
    return result;
}



//------------------------------------------------------------------------------


TEST_FUNCTION(TestAPINLedGetDeviceInfo)
{
    TEST_ENTRY;

    INT result = TPR_FAIL;
    BOOL nled_result;
    UCHAR lednumber;
    NLED_COUNT_INFO countInfo;
    NLED_SETTINGS_INFO SettingsInfo;
    NLED_SUPPORTS_INFO SupportsInfo;
 
    LogMsg(L"Test NLED API NLedGetDeviceInfo\r\n");


    // Test NLED_COUNT_INFO_ID
    nled_result = NLedGetDeviceInfo( NLED_COUNT_INFO_ID, &countInfo);

    if( !nled_result )
    {
        LogMsg(L"Failed NLedGetDeviceInfo NLED_COUNT_INFO_ID\r\n");
        goto cleanUp;
    }

    if( countInfo.cLeds != TOTAL_SYSTEM_LEDS )
    {
        LogMsg(L"GSample reported unexpect (%d) number of system leds.  Expected %d leds.\r\n",countInfo.cLeds, TOTAL_SYSTEM_LEDS);
        goto cleanUp;
    }


    // Test NLED_SUPPORTS_INFO_ID
    for( lednumber = 0; lednumber < countInfo.cLeds; lednumber++)
    {
        SupportsInfo.LedNum = lednumber;
        nled_result = NLedGetDeviceInfo( NLED_SUPPORTS_INFO_ID, &SupportsInfo);

        if( !nled_result )
        {    
            LogMsg(L"Failed NLedGetDeviceInfo NLED_SUPPORTS_INFO_ID for LED %d\r\n", lednumber);
            goto cleanUp;
        }

        LogMsg(L"Got supports info for LED %d\r\n", lednumber);

        if(SupportsInfo.fMetaCycleOn != FALSE)
        {
            LogMsg(L"Reported invalid info (%d) for fMetaCycleOn, expected %d\r\n",SupportsInfo.fMetaCycleOn,FALSE);
            goto cleanUp;
        }
        if(SupportsInfo.fMetaCycleOff != FALSE)
        {
            LogMsg(L"Reported invalid info (%d) for fMetaCycleOff, expected %d\r\n",SupportsInfo.fMetaCycleOff,FALSE);
            goto cleanUp;
        }

        if(SupportsInfo.lCycleAdjust != 62500) 
        {
            LogMsg(L"Reported invalid info (%d) for lCycleAdjust, expected %d\r\n",SupportsInfo.lCycleAdjust,1000);
            goto cleanUp;
        }

        if(SupportsInfo.fAdjustTotalCycleTime != FALSE)
        {
            LogMsg(L"Reported invalid info (%d) for fAdjustTotalCycleTime, expected %d\r\n",SupportsInfo.fAdjustTotalCycleTime,FALSE);
            goto cleanUp;
        }
        if(SupportsInfo.fAdjustOnTime != TRUE)
        {
            LogMsg(L"Reported invalid info (%d) for fAdjustOnTime, expected %d\r\n",SupportsInfo.fAdjustOnTime,TRUE);
            goto cleanUp;
        }
        if(SupportsInfo.fAdjustOffTime != TRUE)
        {
            LogMsg(L"Reported invalid info (%d) for fAdjustOffTime, expected %d\r\n",SupportsInfo.fAdjustOffTime,TRUE);
            goto cleanUp;
        }
    }


    // Test NLED_SETTINGS_INFO_ID
    for( lednumber = 0; lednumber < countInfo.cLeds; lednumber++)
    {
        SettingsInfo.LedNum = lednumber;
        nled_result = NLedGetDeviceInfo( NLED_SETTINGS_INFO_ID, &SettingsInfo);

        if( !nled_result )
        {
            LogMsg(L"Failed NLedGetDeviceInfo NLED_SETTINGS_INFO_ID for LED %d\r\n", lednumber);
            goto cleanUp;
        }

        LogMsg(L"Got settings info for LED %d\r\n", lednumber);

        if(SettingsInfo.TotalCycleTime != SettingsInfo.OnTime + SettingsInfo.OffTime)
        {
            LogMsg(L"Reported invalid info (%d) for TotalCycleTime, expected %d\r\n",SettingsInfo.TotalCycleTime,0);
            goto cleanUp;
        }
    }

    result = TPR_PASS;

cleanUp:
    return result;
}


TEST_FUNCTION(NegTestUnavailableLeds)
{
    TEST_ENTRY;

    INT result = TPR_FAIL;
    BOOL nled_result;
    NLED_COUNT_INFO countInfo;
    
    nled_result = NLedGetDeviceInfo( NLED_COUNT_INFO_ID, &countInfo);
    if ( !nled_result )
    {
        LogMsg(L"Error: COuld not get NLed device driver info.\r\n");
        goto cleanUp;
    }

    LogMsg(L"LED count reported by driver = 0x%x.\r\n",countInfo.cLeds);

    // We expect a set number of LEDs.  This includes the vibrator
    if( countInfo.cLeds != TOTAL_SYSTEM_LEDS )
    {
        LogMsg(L"GSample reported unexpect (%d) number of system leds.  Expected %d leds.\r\n",countInfo.cLeds, TOTAL_SYSTEM_LEDS);
        goto cleanUp;
    }


    LogMsg(L"Blinking unavailable led %d.\r\n",countInfo.cLeds);
    if( BlinkLed( countInfo.cLeds ) )
    {
        LogMsg(L"Blink led failure for led %d.\r\n", countInfo.cLeds);
        goto cleanUp;
    }

    result = TPR_PASS;

cleanUp:
    return result;
}

//------------------------------------------------------------------------------

TEST_FUNCTION(NegTestInvalidState)
{
    TEST_ENTRY;
    UCHAR lednumber;
    INT result = TPR_FAIL;
    BOOL nled_result;
    NLED_COUNT_INFO countInfo;
    NLED_SETTINGS_INFO SettingsInfo;
 
    nled_result = NLedGetDeviceInfo( NLED_COUNT_INFO_ID, &countInfo);
    if ( !nled_result )
    {
        LogMsg(L"Error: COuld not get NLed device driver info.\r\n");
        goto cleanUp;
    }

    LogMsg(L"LED count reported by driver = 0x%x.\r\n",countInfo.cLeds);

    // We expect a set number of LEDs.  This includes the vibrator
    if( countInfo.cLeds != TOTAL_SYSTEM_LEDS )
    {
        LogMsg(L"GSample reported unexpect (%d) number of system leds.  Expected %d leds.\r\n",countInfo.cLeds, TOTAL_SYSTEM_LEDS);
        goto cleanUp;
    }


    for( lednumber=0; lednumber<countInfo.cLeds; lednumber++)
    {
        SettingsInfo.LedNum = lednumber;
        SettingsInfo.OffOnBlink = 32;
        SettingsInfo.MetaCycleOn=0;
        SettingsInfo.MetaCycleOff=0;
        SettingsInfo.OnTime=200*1000;
        SettingsInfo.OffTime=200*1000;
        LogMsg(L"Test an invalid state on led %d.\r\n",SettingsInfo.LedNum);
        
        nled_result = NLedSetDevice( NLED_SETTINGS_INFO_ID, &SettingsInfo);

        if( nled_result )
        {
            LogMsg(L"Invalid state succeeded, it shouldn't have.\r\n");
            goto cleanUp;
        }
    }

    result = TPR_PASS;

cleanUp:
    return result;
}
